home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / c / awin / ddazure2.asm < prev    next >
Assembly Source File  |  1999-05-17  |  10KB  |  556 lines

  1. ; FILE: GG:src/own/awin/ddazure2.ASM    REV: 6 --- ultrafast scaling routines by Azure
  2. ; LINK: >LEAVEOBJ>
  3. ; History
  4. ;  0      1st Dec 1998. Got source & permission to use it from Azure.
  5. ;         did you already know I love Azure :)
  6. ;  1      adapted to use stack for temp, figured out some stuff:)
  7. ;  2      wrote bad _awddscalech68k with nice 1:1, 2:1 and 1:2 routines
  8. ;  3      wrote nice 1:1, 2:1 and 1:2 routines to _awddremapscalech68k
  9. ;  4      hmmph.
  10. ;  5      _awddremapscalech68k8 .samex trashed 12(a5) and 4(a5).
  11. ;  6      fixed one line overflow from all functions :)
  12. ;
  13.  
  14. ; Oh btw don't blame Azure if these routines seem bad :)
  15.  
  16.     XDEF    _awddscalech68k8
  17.     XDEF    _awddremapscalech68k8
  18.  
  19.     XDEF    _awddscalech68k16
  20.     XDEF    _awddremapscalech68k16
  21.     XDEF    _awddscalech68k16_565
  22.     XDEF    _awddscalech68k16_argb
  23.  
  24.  
  25. asc_addstartb    EQU    0
  26. asc_ycnt    EQU    4 ; obviously using both asc_ycnt and asc_yadd
  27. asc_yadd    EQU    4 ; at the same time is a BAD idea.. ;)
  28. asc_xlongs    EQU    8
  29. asc_chunkywidth    EQU    12
  30. asc_modulo    EQU    16
  31. asctemp_SIZEOF    EQU    20
  32.  
  33. ;in:
  34. ;d0.l/d1.l source width/height
  35. ;d2.l/d3.l destination width/height
  36. ;d4.l destination width aligned (aligned with 16,32,64 etc)
  37. ;d5.l destination pixperrow
  38. ;a0 destination
  39. ;a2 source
  40.  
  41.     CNOP    0,8
  42. _awddscalech68k8:
  43.     movem.l    d2-d7/a2-a6,-(sp)
  44.  
  45.     cmp.w    d0,d2
  46.     beq    .samex
  47.  
  48.     lea    (-asctemp_SIZEOF,sp),sp
  49.     sub.l    d4,d5
  50.     move.l    sp,a5
  51.     move.l    d5,asc_modulo(a5)
  52.     move.l    d0,asc_chunkywidth(a5)
  53.  
  54.     lsl.l    #8,d0
  55.     lsl.l    #8,d1
  56.     divu.w    d2,d0
  57.     divu.w    d3,d1    ;8.8 accuracy
  58.     ext.l    d0
  59.     ext.l    d1
  60.  
  61.     cmp.w    #(1<<8)>>1,d0
  62.     beq    .doublex
  63.     cmp.w    #(1<<8)<<1,d0
  64.     beq    .halvex
  65.  
  66.     move.l    d0,d7
  67.  
  68.     moveq    #0,d5
  69.     move.b    d0,d5    ;fraction
  70.     ror.l    #8,d5
  71.     move.l    d5,a3    ;addstart a
  72.     ror.l    #7,d0
  73.     move.l    d0,d7    ;adder
  74.     move.l    d0,d5
  75.     ror.l    #1,d0
  76.     move.w    d0,d5    ;addstart b
  77.     move.l    d5,(a5)
  78.  
  79.     move.l    d1,a4
  80.     lsr.l    #2,d4
  81.     move.l    d4,asc_xlongs(a5)
  82.  
  83.     clr.l    asc_ycnt(a5)
  84. .ylop
  85.     move.l    (a5),d6
  86.  
  87.     move.l    asc_ycnt(a5),d4
  88.     move.l    d4,d2
  89.     lsr.l    #8,d4
  90.     mulu.w    asc_chunkywidth+2(a5),d4
  91.     lea    (a2,d4.l),a1
  92.     add.l    a4,d2
  93.     move.l    d2,asc_ycnt(a5)
  94.  
  95.     move.l    a3,d0
  96.  
  97.     move.w    asc_xlongs+2(a5),d4
  98.     subq.w    #1,d4        ;clear x-flag
  99. .xlop
  100.     move.w    (a1,d0.w),d5    ;this definetely sucks
  101.     addx.l    d7,d0
  102.     move.b    (a1,d6.w),d5
  103.     addx.l    d7,d6
  104.     swap    d5
  105.     move.w    (a1,d0.w),d5
  106.     addx.l    d7,d0
  107.     move.b    (a1,d6.w),d5
  108.     move.l    d5,(a0)+
  109.     addx.l    d7,d6
  110.  
  111.     dbf    d4,.xlop    ; can NOT subq!!
  112.     add.l    asc_modulo(a5),a0 ;add modulo
  113.     subq.w    #1,d3
  114.     bne.b    .ylop
  115.     bra    .exit
  116.  
  117.  
  118.     CNOP    0,4
  119. .samex    move.l    d5,a4
  120.     lsl.l    #8,d1
  121.     sub.l    d4,a4    ;a4=modulo=pixperrow-width_aligned
  122.     divu.w    d3,d1    ;8.8 accuracy
  123.     ext.l    d1
  124.  
  125.     lsr.l    #4,d4    ;/16 (four longs at a time)
  126.     move.l    d4,a3
  127.  
  128.     moveq    #0,d2
  129. .sylop    move.l    d2,d5
  130.     move.l    a3,d4
  131.     lsr.l    #8,d5
  132.     mulu.w    d0,d5
  133.     add.l    d1,d2
  134.     lea    (a2,d5.l),a1
  135.  
  136. .sxlop    move.l    (a1)+,(a0)+
  137.     move.l    (a1)+,(a0)+
  138.     move.l    (a1)+,(a0)+
  139.     move.l    (a1)+,(a0)+
  140.  
  141.     subq.l    #1,d4
  142.     bne.b    .sxlop
  143.     add.l    a4,a0        ;add modulo
  144.     subq.w    #1,d3
  145.     bne.b    .sylop
  146.     bra    .sexit    ; it's .samex exit you perv
  147.  
  148.  
  149.     CNOP    0,4
  150. .doublex    move.l    asc_chunkywidth(a5),d6
  151.  
  152.     lsr.l    #3,d4    ;/8 (two longs at a time)
  153.     moveq    #16,d7
  154.     move.l    d4,a3
  155.  
  156.     moveq    #0,d2
  157.  
  158. .dylop    move.l    d2,d5
  159.     move.l    a3,d4
  160.     lsr.l    #8,d5
  161.     mulu.w    d6,d5
  162.     add.l    d1,d2
  163.     lea    (a2,d5.l),a1
  164.  
  165. .dxlop    move.w    (a1),d0        ;--ab
  166.     move.w    (2,a1),d5    ;--cd
  167.     move.b    (a1),d0        ;--aa
  168.     move.b    (2,a1),d5    ;--cc
  169.     lsl.l    d7,d0        ;aa--
  170.     lsl.l    d7,d5        ;cc--
  171.     move.w    (1,a1),d0    ;aabc
  172.     move.w    (3,a1),d5    ;ccde
  173.     move.b    (1,a1),d0    ;aabb
  174.     move.b    (3,a1),d5    ;ccdd
  175.     move.l    d0,(a0)+
  176.     addq.l    #4,a1
  177.     move.l    d5,(a0)+
  178.  
  179.     subq.w    #1,d4
  180.     bne.b    .dxlop
  181.     add.l    asc_modulo(a5),a0 ;add modulo
  182.     subq.w    #1,d3
  183.     bne.b    .dylop
  184.     bra    .exit
  185.  
  186.  
  187.     CNOP    0,4
  188. .halvex    move.l    asc_chunkywidth(a5),d6
  189.  
  190.     lsr.l    #3,d4    ;/8 (two longs at a time)
  191.     moveq    #16,d7
  192.     move.l    d4,a3
  193.  
  194.     moveq    #0,d2
  195.  
  196. .hylop    move.l    d2,d5
  197.     move.l    a3,d4
  198.     lsr.l    #8,d5
  199.     mulu.w    d6,d5
  200.     add.l    d1,d2
  201.     lea    (a2,d5.l),a1
  202.  
  203. .hxlop    move.w    (a1),d0        ;--ab
  204.     move.w    (8,a1),d5    ;--ij
  205.     move.b    (2,a1),d0    ;--ac
  206.     move.b    (10,a1),d5    ;--ik
  207.     lsl.l    d7,d0        ;ac--
  208.     lsl.l    d7,d5        ;ik--
  209.     move.w    (4,a1),d0    ;acef
  210.     move.w    (12,a1),d5    ;ikmn
  211.     move.b    (6,a1),d0    ;aceg
  212.     move.b    (14,a1),d5    ;ikmo
  213.     move.l    d0,(a0)+
  214.     add.l    d7,a1
  215.     move.l    d5,(a0)+
  216.  
  217.     subq.w    #1,d4
  218.     bne.b    .hxlop
  219.     add.l    asc_modulo(a5),a0 ;add modulo
  220.     subq.w    #1,d3
  221.     bne.b    .hylop
  222.  
  223.  
  224. .exit    lea    (asctemp_SIZEOF,sp),sp
  225. .sexit    movem.l    (sp)+,d2-d7/a2-a6
  226.     rts
  227.  
  228.  
  229. ;in:
  230. ;d0.l/d1.l source width/height
  231. ;d2.l/d3.l destination width/height
  232. ;d4.l destination width aligned (aligned with 16,32,64 etc)
  233. ;a0 destination
  234. ;a2 source
  235. ;a6 remap (palette LUT)
  236.  
  237.     CNOP    0,8
  238. _awddremapscalech68k8:
  239.     movem.l    d2-d7/a2-a6,-(sp)
  240.  
  241.     lea    (-asctemp_SIZEOF,sp),sp
  242.     move.l    sp,a5
  243.  
  244.     move.l    d0,asc_chunkywidth(a5)
  245.  
  246.     cmp.w    d0,d2
  247.     beq    .samex
  248.  
  249.     move.l    d0,d7
  250.     lsl.l    #8,d7
  251.     divu.w    d2,d7
  252.  
  253.     addq.l    #1,d2    ;handle leftmost pix
  254.     lsl.l    #8,d0
  255.     lsl.l    #8,d1
  256.     divu.w    d2,d0
  257.     divu.w    d3,d1    ;8.8 accuracy
  258.     ext.l    d0
  259.     ext.l    d1
  260.  
  261.     cmp.w    #(1<<8)>>1,d7
  262.     beq    .doublex
  263.     cmp.w    #(1<<8)<<1,d7
  264.     beq    .halvex
  265.  
  266.     move.l    d0,d7
  267.  
  268.     moveq    #0,d5
  269.     move.b    d0,d5    ;fraction
  270.     ror.l    #8,d5
  271.     move.l    d5,a3    ;addstart a
  272.     ror.l    #7,d0
  273.     move.l    d0,d7    ;adder
  274.     move.l    d0,d5
  275.     ror.l    #1,d0
  276.     move.w    d0,d5    ;addstart b
  277.     move.l    d5,(a5)
  278.  
  279.     move.l    d1,a4
  280.     lsr.l    #2,d4
  281.     move.l    d4,asc_xlongs(a5)
  282.  
  283.     clr.l    asc_ycnt(a5)
  284.     moveq    #0,d1
  285. .ylop
  286.     move.l    (a5),d6
  287.  
  288.     move.l    asc_ycnt(a5),d4
  289.     move.l    d4,d2
  290.     lsr.l    #8,d4
  291.     mulu.w    asc_chunkywidth+2(a5),d4
  292.     lea    (a2,d4.l),a1
  293.     add.l    a4,d2
  294.     move.l    d2,asc_ycnt(a5)
  295.  
  296.     move.l    a3,d0
  297.  
  298.     moveq    #0,d2
  299.     move.w    asc_xlongs+2(a5),d4
  300.     move.b    (a1,d6.w),d2    ;handle leftmost pix
  301.     subq.w    #1,d4        ;clear x-flag
  302.     addx.l    d7,d0        ;handle leftmost pix
  303.     addx.l    d7,d6        ;handle leftmost pix
  304. .xlop
  305.     move.b    (a1,d0.w),d1    *x
  306.     move.w    (a6,d2.w),d5    *
  307.     addx.l    d7,d0        *    3++ cycles per pixel
  308.     move.b    (a1,d6.w),d2
  309.     move.b    (a6,d1.w),d5
  310.     addx.l    d7,d6
  311.     swap    d5
  312.     move.b    (a1,d0.w),d1
  313.     move.w    (a6,d2.w),d5
  314.     addx.l    d7,d0
  315.     move.b    (a1,d6.w),d2
  316.     move.b    (a6,d1.w),d5
  317.     move.l    d5,(a0)+
  318.     addx.l    d7,d6
  319.  
  320.     dbf    d4,.xlop    ; can NOT subq!!
  321.     subq.w    #1,d3
  322.     bne.b    .ylop
  323.     bra    .exit
  324.  
  325.  
  326.     CNOP    0,4
  327. .samex    lsl.l    #8,d1
  328.     divu.w    d3,d1    ;8.8 accuracy
  329.     ext.l    d1
  330.     move.l    d1,asc_yadd(a5)
  331.  
  332.     lsr.l    #3,d4    ;/8 (two longs at a time)
  333.     move.l    d4,a3
  334.  
  335.     moveq    #0,d6
  336.     moveq    #16,d7
  337.  
  338.     moveq    #0,d2
  339. .sylop    move.l    d2,d5
  340.     move.w    a3,d4
  341.     lsr.l    #8,d5
  342.     mulu.w    asc_chunkywidth+2(a5),d5
  343.     add.l    asc_yadd(a5),d2
  344.     lea    (a2,d5.l),a1
  345.  
  346.     IFGT    1
  347.     moveq    #0,d5        ;could be faster
  348. .sxlop    move.b    (a1),d6
  349.     move.b    (4,a1),d5
  350.     move.w    (a6,d6.l),d0
  351.     move.b    (1,a1),d6
  352.     move.w    (a6,d5.l),d1
  353.     move.b    (5,a1),d5
  354.     move.b    (a6,d6.l),d0
  355.     move.b    (a6,d5.l),d1
  356.     lsl.l    d7,d0
  357.     lsl.l    d7,d1
  358.     move.b    (2,a1),d6
  359.     move.b    (6,a1),d5
  360.     move.w    (a6,d6.l),d0
  361.     move.b    (3,a1),d6
  362.     move.w    (a6,d5.l),d1
  363.     move.b    (7,a1),d5
  364.     move.b    (a6,d6.l),d0
  365.     move.b    (a6,d5.l),d1
  366.     move.l    d0,(a0)+
  367.     addq.l    #8,a1
  368.     move.l    d1,(a0)+
  369.     ELSE
  370. .sxlop    move.b    (a1),d6
  371.     move.b    (1,a1),d7
  372.     move.b    (a6,d6.w),d1
  373.     lsl.l    #8,d1
  374.     move.b    (2,a1),d6
  375.     move.b    (a6,d7.w),d1
  376.     lsl.l    #8,d1
  377.     move.b    (3,a1),d7
  378.     move.b    (a6,d6.w),d1
  379.     lsl.l    #8,d1
  380.     move.b    (4,a1),d6
  381.     move.b    (a6,d7.w),d1
  382.     move.b    (5,a1),d7
  383.     move.b    (a6,d6.w),d5
  384.     lsl.l    #8,d5
  385.     move.b    (6,a1),d6
  386.     move.b    (a6,d7.w),d5
  387.     lsl.l    #8,d5
  388.     move.b    (7,a1),d7
  389.     move.b    (a6,d6.w),d5
  390.     lsl.l    #8,d5
  391.     addq.l    #8,a1
  392.     move.b    (a6,d7.w),d5
  393.     move.l    d1,(a0)+
  394.     move.l    d5,(a0)+
  395.     ENDC
  396.  
  397.     subq.w    #1,d4
  398.     bne.b    .sxlop
  399.     subq.w    #1,d3
  400.     bne.b    .sylop
  401.     bra    .exit
  402.  
  403.  
  404.     CNOP    0,4
  405. .doublex    move.l    d1,asc_yadd(a5)
  406.  
  407.     lsr.l    #3,d4    ;/8 (two longs at a time)
  408.     moveq    #16,d7
  409.     move.l    d4,a3
  410.  
  411.     moveq    #0,d0
  412.     moveq    #0,d6
  413.  
  414.     moveq    #0,d2
  415.  
  416. .dylop    move.l    d2,d5
  417.     move.l    a3,d4
  418.     lsr.l    #8,d5
  419.     mulu.w    asc_chunkywidth+2(a5),d5
  420.     add.l    asc_yadd(a5),d2
  421.     lea    (a2,d5.l),a1
  422.  
  423. .dxlop    move.b    (a1),d6        ;a pix
  424.     move.b    (2,a1),d0    ;c pix
  425.     move.w    (a6,d6.l),d5    ;--a-
  426.     move.w    (a6,d0.l),d1    ;--c-
  427.     move.b    (a6,d6.l),d5    ;--aa
  428.     move.b    (a6,d0.l),d1    ;--cc
  429.     lsl.l    d7,d5        ;aa--
  430.     lsl.l    d7,d1        ;cc--
  431.     move.b    (1,a1),d6    ;b pix
  432.     move.b    (3,a1),d0    ;d pix
  433.     move.w    (a6,d6.l),d5    ;aab-
  434.     move.w    (a6,d0.l),d1    ;ccd-
  435.     move.b    (a6,d6.l),d5    ;aabb
  436.     move.b    (a6,d0.l),d1    ;ccdd
  437.     move.l    d5,(a0)+
  438.     addq.l    #4,a1
  439.     move.l    d1,(a0)+
  440.  
  441.     subq.l    #1,d4
  442.     bne.b    .dxlop
  443.     subq.w    #1,d3
  444.     bne.b    .dylop
  445.     bra    .exit
  446.  
  447.  
  448.     CNOP    0,4
  449. .halvex    move.l    d1,asc_yadd(a5)
  450.  
  451.     lsr.l    #3,d4    ;/8 (two longs at a time)
  452.     moveq    #16,d7
  453.     move.l    d4,a3
  454.  
  455.     moveq    #0,d0
  456.     moveq    #0,d6
  457.  
  458.     moveq    #0,d2
  459.  
  460. .hylop    move.l    d2,d5
  461.     move.l    a3,d4
  462.     lsr.l    #8,d5
  463.     mulu.w    asc_chunkywidth+2(a5),d5
  464.     add.l    asc_yadd(a5),d2
  465.     lea    (a2,d5.l),a1
  466.  
  467. .hxlop    move.b    (a1),d6        ;a pix
  468.     move.b    (8,a1),d0    ;i pix
  469.     move.w    (a6,d6.l),d5    ;--a-
  470.     move.b    (2,a1),d6    ;c pix
  471.     move.w    (a6,d0.l),d1    ;--i-
  472.     move.b    (10,a1),d